home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Games / MoofWars / MoofEncoder / GridEncode.cp < prev    next >
Encoding:
Text File  |  2000-09-28  |  8.4 KB  |  287 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        GridEncode.cp
  3.  
  4.     Contains:    This is just a very simple encoder that shows how to build GRID and TILE resources.
  5.                 The TILE resource is a set of 32x32x1 byte tiles.  This encoder takes a picture and
  6.                 dices it into 32x32 tiles, which it writes out to output file.  It then builds a
  7.                 standard grid, repeating the original picture as a pattern across the grid.
  8.     
  9.                 Eventually, it would be nice to make a program that lets someone graphically edit
  10.                 the available list of tiles and the actual GRID resource, much like any number
  11.                 of map editors out for various games.
  12.  
  13.     Written by: Timothy Carroll    
  14.  
  15.     Copyright:    Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
  16.  
  17.                 You may incorporate this Apple sample source code into your program(s) without
  18.                 restriction. This Apple sample source code has been provided "AS IS" and the
  19.                 responsibility for its operation is yours. You are not permitted to redistribute
  20.                 this Apple sample source code as "Apple sample source code" after having made
  21.                 changes. If you're going to re-distribute the source, we require that you make
  22.                 it clear in the source that the code was descended from Apple sample source
  23.                 code, but that you've made changes.
  24.  
  25.     Change History (most recent first):
  26.                 7/1/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  27.                 2/24/97        Timothy Carroll    Now explicitly include main.h
  28.                 8/15/96        Timothy Carroll Initial Release
  29.                 
  30.  
  31. */
  32.  
  33. #include <Resources.h>
  34. #include "Main.h"
  35. #include "GridEncode.h"
  36. #include "GridTilesFormat.h"
  37. #include "Error Macros.h"
  38.  
  39.  
  40. OSStatus GridTileEncode (short inputFileResNum, short outputFileResNum)
  41. {
  42.     OSStatus        theErr;
  43.     short            saveResNum;
  44.     
  45.     // Used to compile the tile resource
  46.     PicHandle        tilePict = NULL;
  47.     GWorldPtr        tileWorld = NULL;
  48.     PixMapHandle    tilePix = NULL;
  49.     
  50.     CGrafPtr         savePort;
  51.     GDHandle         saveDevice;
  52.     
  53.     Rect            pictRect;
  54.  
  55.     long            width, height, numTiles;
  56.     long            tileRowBytes;
  57.     Ptr                tileBaseAddress;
  58.     
  59.     long            x, y, loop;
  60.     
  61.     Ptr                destPtr, srcPtr;
  62.     CellGridType    *gridPtr;
  63.     CellGridType    currentValue;
  64.     
  65.     // Our output handles
  66.     Handle            tile = NULL;
  67.     Handle            grid = NULL;
  68.     
  69.     // Whether or not we've written it out as a resource
  70.     Boolean            tileIsResource = false, gridIsResource = false;
  71.         
  72.     saveResNum = CurResFile();
  73.  
  74.     UseResFile (inputFileResNum);
  75.  
  76.  
  77.     // First thing is to copy the color table resource to the output.
  78.     theErr = CopyResource (inputFileResNum, outputFileResNum,'clut', kAppColorTableResID);
  79.     FAIL_OSERR (theErr, "\pFailed to copy the color table to the destination file")
  80.  
  81.     // Load the color table and the graphic we want to dice into pieces
  82.     gAppColorTable = GetCTable( kAppColorTableResID );
  83.     FAIL_NIL (gAppColorTable, "\pFailed to load the color table")
  84.     
  85.     tilePict = (PicHandle) Get1Resource ('PICT', kPICTInputResID);
  86.     theErr = ResError();
  87.     FAIL_OSERR (theErr, "\pFailed to load the pict")
  88.     FAIL_NIL (tilePict, "\pFailed to load the pict")
  89.  
  90.  
  91.     
  92.     // Create a GWorld and draw our PICT into it.
  93.     
  94.     pictRect = (**tilePict).picFrame;
  95.     
  96.     pictRect.right -= pictRect.left;
  97.     pictRect.left = 0;
  98.     pictRect.bottom -= pictRect.top;
  99.     pictRect.top = 0;
  100.     
  101.     theErr = NewGWorld(&tileWorld, kPreferredDepth, &pictRect, gAppColorTable, NULL, keepLocal);
  102.     FAIL_OSERR (theErr, "\pCouldn't allocate GWorld for encoding")
  103.     FAIL_NIL (tileWorld, "\pCouldn't allocate GWorld for encoding")
  104.     
  105.     tilePix  = GetGWorldPixMap(tileWorld);
  106.     FAIL_NIL (tilePix, "\pCouldn't get the GWorld's PixMap")
  107.     FAIL_FALSE ( LockPixels(tilePix), "\pCouldn't lock GWorld PixMap")
  108.     
  109.     GetGWorld (&savePort, &saveDevice);
  110.     SetGWorld (tileWorld, NULL);
  111.     
  112.     EraseRect (&pictRect);
  113.     DrawPicture (tilePict, &pictRect);
  114.     
  115.     SetGWorld (savePort, saveDevice);
  116.  
  117.     // We're done with the picture, release it
  118.     ReleaseResource ((Handle) tilePict);
  119.     tilePict = NULL;
  120.  
  121.     // Time to build the tile resource.  We're going to dice it into as many
  122.     // 32x32 tiles as we can.  Any partial data to the bottom or the right will
  123.     // be ignored -- we only build complete tiles.
  124.     
  125.     width = pictRect.right / 32;
  126.     height = pictRect.bottom / 32;
  127.     numTiles = width * height + 1;  // Our first tile is always an all black tile, for the "borders"
  128.     
  129.     tile = NewHandleClear (sizeof (TileCollectionResHeader) + numTiles*kTileSize);
  130.     theErr = MemError();
  131.     FAIL_OSERR (theErr, "\p Failed to create the tile resource file")
  132.     FAIL_NIL (tile, "\p Failed to create the tile resource file")
  133.  
  134.     // Fill in the tile header.
  135.     (**((TileCollectionResHeader **) tile)).version = 0;
  136.     (**((TileCollectionResHeader **) tile)).depth = kPreferredDepth;
  137.     (**((TileCollectionResHeader **) tile)).flags = 0;
  138.     (**((TileCollectionResHeader **) tile)).numTiles = numTiles;
  139.     
  140.     tileBaseAddress = ( Ptr) GetPixBaseAddr( tilePix );
  141.     tileRowBytes = ( **tilePix ).rowBytes & 0x3fff;
  142.     
  143.     destPtr = (*tile) + sizeof (TileCollectionResHeader);
  144.     
  145.     // First tile, we just fill with black
  146.     for (loop = 0; loop < 32; loop++)
  147.     {
  148.         ((UInt32 *) destPtr)[0] = 0xFFFFFFFF;
  149.         ((UInt32 *) destPtr)[1] = 0xFFFFFFFF;
  150.         ((UInt32 *) destPtr)[2] = 0xFFFFFFFF;
  151.         ((UInt32 *) destPtr)[3] = 0xFFFFFFFF;
  152.         ((UInt32 *) destPtr)[4] = 0xFFFFFFFF;
  153.         ((UInt32 *) destPtr)[5] = 0xFFFFFFFF;
  154.         ((UInt32 *) destPtr)[6] = 0xFFFFFFFF;
  155.         ((UInt32 *) destPtr)[7] = 0xFFFFFFFF;
  156.         destPtr += 32;
  157.     }
  158.  
  159.     // Iterate over each tile and copy 1K of data to the destination
  160.     for (x = 0; x < width; x++)
  161.     {
  162.         for (y = 0; y < height; y++)
  163.         {
  164.             srcPtr = tileBaseAddress + 32*y*tileRowBytes + 32*x;
  165.             for (loop = 0; loop < 32; loop++)
  166.             {
  167.                 register UInt32 temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8;
  168.                 temp1 = ((UInt32 *) srcPtr)[0];
  169.                 temp2 = ((UInt32 *) srcPtr)[1];
  170.                 temp3 = ((UInt32 *) srcPtr)[2];
  171.                 temp4 = ((UInt32 *) srcPtr)[3];
  172.                 temp5 = ((UInt32 *) srcPtr)[4];
  173.                 temp6 = ((UInt32 *) srcPtr)[5];
  174.                 temp7 = ((UInt32 *) srcPtr)[6];
  175.                 temp8 = ((UInt32 *) srcPtr)[7];
  176.                 ((UInt32 *) destPtr)[0] = temp1;
  177.                 ((UInt32 *) destPtr)[1] = temp2;
  178.                 ((UInt32 *) destPtr)[2] = temp3;
  179.                 ((UInt32 *) destPtr)[3] = temp4;
  180.                 ((UInt32 *) destPtr)[4] = temp5;
  181.                 ((UInt32 *) destPtr)[5] = temp6;
  182.                 ((UInt32 *) destPtr)[6] = temp7;
  183.                 ((UInt32 *) destPtr)[7] = temp8;
  184.                 srcPtr += tileRowBytes;
  185.                 destPtr += 32;
  186.             }
  187.         }
  188.     }
  189.     
  190.     // Tile resource is done.  Dispose of the GWorld
  191.     DisposeGWorld ( tileWorld);
  192.     tileWorld = NULL;
  193.     
  194.     
  195.     // Time to create the GRID resource
  196.     grid = NewHandle (sizeof (TileGridResHeader) + 
  197.                             sizeof (CellGridType)*kGridWidth*kGridHeight);
  198.     theErr = MemError();
  199.     FAIL_OSERR (theErr, "\p Failed to allocate memory for GRID resource")
  200.     FAIL_NIL (grid, "\p Failed to allocate memory for GRID resource")
  201.     
  202.     // Fill in the header
  203.     (**((TileGridResHeader **) grid)).version = 0;
  204.     (**((TileGridResHeader **) grid)).flags = 0;
  205.     (**((TileGridResHeader **) grid)).tileResID = kOutputResID;
  206.     (**((TileGridResHeader **) grid)).width = kGridWidth;
  207.     (**((TileGridResHeader **) grid)).height = kGridHeight;
  208.     (**((TileGridResHeader **) grid)).defaultTile = 0;  // our black tile
  209.     
  210.     // Point to the start of the grid data.
  211.     gridPtr = (CellGridType * ) ((Ptr)(*grid) + sizeof (TileGridResHeader));
  212.     
  213.     // Fill in each tile
  214.     for (x = 0; x < kGridWidth; x++)
  215.     {
  216.         for (y = 0; y < kGridWidth; y++)
  217.         {
  218.             currentValue = (y % height)*height + (x % width) +1;
  219.             *gridPtr = currentValue;
  220.             gridPtr++;
  221.         }
  222.     }
  223.  
  224.     // Write the resources out to the output file.
  225.     UseResFile (outputFileResNum);
  226.     
  227.     AddResource( tile, TileCollectionResType, kOutputResID, "\p" );
  228.     theErr = ResError();
  229.     FAIL_OSERR (theErr, "\pFailed to add the TILE resource to the file")
  230.     tileIsResource = true;  
  231.     
  232.     WriteResource( tile );
  233.     theErr = ResError();
  234.     FAIL_OSERR (theErr, "\pFailed to write the TILE resource to the file")
  235.     
  236.     ReleaseResource( tile );
  237.     tile = NULL;
  238.  
  239.     AddResource( grid, TileGridResType, kOutputResID, "\p" );
  240.     theErr = ResError();
  241.     FAIL_OSERR (theErr, "\pFailed to add the GRID resource to the file")
  242.     gridIsResource = true;
  243.     
  244.     WriteResource( grid );
  245.     FAIL_OSERR (theErr, "\pFailed to write the GRID resource to the file")
  246.     theErr = ResError();
  247.     
  248.     ReleaseResource( grid );
  249.     grid = NULL;
  250.  
  251.         
  252.     // Build the grid resource;
  253.     
  254.     goto cleanup;
  255.     
  256.     error:
  257.     if (theErr == noErr)
  258.         theErr = paramErr;
  259.         
  260.     cleanup:
  261.     
  262.     UseResFile (saveResNum);
  263.     
  264.     if (tilePict != NULL)
  265.         ReleaseResource ((Handle) tilePict);
  266.         
  267.     if (tileWorld != NULL)
  268.         DisposeGWorld (tileWorld);
  269.         
  270.     if (gAppColorTable != NULL)
  271.         DisposeCTable (gAppColorTable);        
  272.     gAppColorTable = NULL;
  273.     
  274.     if (tile)
  275.         if (tileIsResource)
  276.             ReleaseResource (tile);
  277.         else
  278.             DisposeHandle (tile); 
  279.             
  280.     if (grid)
  281.         if (gridIsResource)
  282.             ReleaseResource (grid);
  283.         else
  284.             DisposeHandle (grid);
  285.     return theErr;
  286. }
  287.